﻿using System.Collections.Generic;
using System.Linq;

namespace VH6I_B4.ProductParsing
{
    class ProductParser
    {
        Dictionary<ProductLevel, string> parserResults = new Dictionary<ProductLevel, string>();

        public ProductParser()
        {
        }

        public Dictionary<ProductLevel, string> Parse(string rawProduct)
        {
            rawProduct = rawProduct.Trim();
            List<string> rawProductList = rawProduct.Split(' ').ToList();

            // MAJOR.BRAND
            if (!parserResults.ContainsKey(ProductLevel.MAJOR_BRAND))
            {
                parserResults.Add(ProductLevel.MAJOR_BRAND, rawProduct);
            }
            else if (!rawProduct.Contains(parserResults[ProductLevel.MAJOR_BRAND]))
            {
                parserResults[ProductLevel.MAJOR_BRAND] = rawProduct;
                ClearLevels(ProductLevel.MAJOR_BRAND);
            }

            // APPARAAT
            if (!parserResults.ContainsKey(ProductLevel.APPARAAT) && parserResults.ContainsKey(ProductLevel.MAJOR_BRAND))
            {
                List<string> apparaatWords = new List<string>();

                for (int i = parserResults[ProductLevel.MAJOR_BRAND].Split(' ').Length; i < rawProductList.Count; i++)
                {
                    apparaatWords.Add(rawProductList[i].Trim());
                }

                if (apparaatWords.Count != 0)
                    parserResults[ProductLevel.APPARAAT] = string.Join(" ", apparaatWords.ToArray());
            }
            else if (parserResults.ContainsKey(ProductLevel.APPARAAT) && !(rawProduct.Contains('(') && rawProduct.Contains(')')))
            {
                List<string> apparaatWords = new List<string>();

                if (!rawProduct.Contains(parserResults[ProductLevel.APPARAAT]))
                {
                    for (int i = parserResults[ProductLevel.MAJOR_BRAND].Split(' ').Length; i < rawProductList.Count; i++)
                    {
                        apparaatWords.Add(rawProductList[i].Trim());
                    }

                    ClearLevels(ProductLevel.APPARAAT);
                }

                if (apparaatWords.Count != 0)
                    parserResults[ProductLevel.APPARAAT] = string.Join(" ", apparaatWords.ToArray());
            }

            // TYPE
            if (!parserResults.ContainsKey(ProductLevel.TYPE) && parserResults.ContainsKey(ProductLevel.APPARAAT))
            {
                List<string> typeWords = new List<string>();

                for (int i = parserResults[ProductLevel.MAJOR_BRAND].Split(' ').Length + parserResults[ProductLevel.APPARAAT].Split(' ').Length; i < rawProductList.Count; i++)
                {
                    typeWords.Add(rawProductList[i].Trim());
                }

                if (typeWords.Count != 0)
                    parserResults[ProductLevel.TYPE] = string.Join(" ", typeWords.ToArray());
            }
            else if (parserResults.ContainsKey(ProductLevel.TYPE) && !(rawProduct.Contains('(') && rawProduct.Contains(')')))
            {
                List<string> typeWords = new List<string>();

                if (!rawProduct.Contains(parserResults[ProductLevel.TYPE]))
                {
                    for (int i = parserResults[ProductLevel.MAJOR_BRAND].Split(' ').Length + parserResults[ProductLevel.APPARAAT].Split(' ').Length; i < rawProductList.Count; i++)
                    {
                        typeWords.Add(rawProductList[i].Trim());
                    }

                    ClearLevels(ProductLevel.TYPE);
                }

                if (typeWords.Count != 0)
                    parserResults[ProductLevel.TYPE] = string.Join(" ", typeWords.ToArray());
            }

            // BELEVING
            if (!parserResults.ContainsKey(ProductLevel.BELEVING) && parserResults.ContainsKey(ProductLevel.TYPE))
            {
                List<string> belevingWords = new List<string>();

                for (int i = parserResults[ProductLevel.MAJOR_BRAND].Split(' ').Length + parserResults[ProductLevel.APPARAAT].Split(' ').Length + parserResults[ProductLevel.TYPE].Split(' ').Length; i < rawProductList.Count; i++)
                {
                    belevingWords.Add(rawProductList[i].Trim());
                }

                if (belevingWords.Count != 0)
                    parserResults[ProductLevel.BELEVING] = string.Join(" ", belevingWords.ToArray());
            }
            else if (parserResults.ContainsKey(ProductLevel.BELEVING) && !(rawProduct.Contains('(') && rawProduct.Contains(')')))
            {
                List<string> belevingWords = new List<string>();

                if (!rawProduct.Contains(parserResults[ProductLevel.BELEVING]))
                {
                    if (!rawProduct.Contains("GR"))
                    {
                        for (int i = parserResults[ProductLevel.MAJOR_BRAND].Split(' ').Length + parserResults[ProductLevel.APPARAAT].Split(' ').Length + parserResults[ProductLevel.TYPE].Split(' ').Length; i < rawProductList.Count; i++)
                        {
                            belevingWords.Add(rawProductList[i].Trim());
                        }

                        ClearLevels(ProductLevel.BELEVING);
                    }
                }

                if (belevingWords.Count != 0)
                    parserResults[ProductLevel.BELEVING] = string.Join(" ", belevingWords.ToArray());
            }

            // SOORT
            if (!parserResults.ContainsKey(ProductLevel.SOORT) && parserResults.ContainsKey(ProductLevel.BELEVING))
            {
                List<string> soortWords = new List<string>();

                for (int i = parserResults[ProductLevel.MAJOR_BRAND].Split(' ').Length + parserResults[ProductLevel.APPARAAT].Split(' ').Length + parserResults[ProductLevel.TYPE].Split(' ').Length + parserResults[ProductLevel.BELEVING].Split(' ').Length; i < rawProductList.Count; i++)
                {
                    soortWords.Add(rawProductList[i]);
                }

                if (soortWords.Count != 0)
                    parserResults[ProductLevel.SOORT] = string.Join(" ", soortWords.ToArray());
            }
            else if (parserResults.ContainsKey(ProductLevel.SOORT) && !(rawProduct.Contains('(') && rawProduct.Contains(')')))
            {
                List<string> soortWords = new List<string>();

                if (!rawProduct.Contains(parserResults[ProductLevel.SOORT]))
                {
                    for (int i = parserResults[ProductLevel.MAJOR_BRAND].Split(' ').Length + parserResults[ProductLevel.APPARAAT].Split(' ').Length + parserResults[ProductLevel.TYPE].Split(' ').Length + parserResults[ProductLevel.BELEVING].Split(' ').Length; i < rawProductList.Count; i++)
                    {
                        if (!rawProductList[i].Trim().Contains(parserResults[ProductLevel.FORMAAT].Split(' ').ToList()[0]))
                            soortWords.Add(rawProductList[i].Trim());
                    }

                    ClearLevels(ProductLevel.SOORT);
                }

                if (soortWords.Count != 0)
                    parserResults[ProductLevel.SOORT] = string.Join(" ", soortWords.ToArray());
            }

            // FORMAAT
            if (!parserResults.ContainsKey(ProductLevel.FORMAAT) && parserResults.ContainsKey(ProductLevel.SOORT))
            {
                List<string> formaatWords = new List<string>();

                for (int i = parserResults[ProductLevel.MAJOR_BRAND].Split(' ').Length + parserResults[ProductLevel.APPARAAT].Split(' ').Length + parserResults[ProductLevel.TYPE].Split(' ').Length + parserResults[ProductLevel.BELEVING].Split(' ').Length + parserResults[ProductLevel.SOORT].Split(' ').Length; i < rawProductList.Count; i++)
                {
                    formaatWords.Add(rawProductList[i]);
                }

                if (formaatWords.Count != 0)
                    parserResults[ProductLevel.FORMAAT] = string.Join(" ", formaatWords.ToArray());
            }
            else if (parserResults.ContainsKey(ProductLevel.FORMAAT) && !(rawProduct.Contains('(') && rawProduct.Contains(')')))
            {
                List<string> formaatWords = new List<string>();

                if (!rawProduct.Contains(parserResults[ProductLevel.FORMAAT]))
                {

                    for (int i = parserResults[ProductLevel.MAJOR_BRAND].Split(' ').Length + parserResults[ProductLevel.APPARAAT].Split(' ').Length + parserResults[ProductLevel.TYPE].Split(' ').Length + parserResults[ProductLevel.BELEVING].Split(' ').Length + parserResults[ProductLevel.SOORT].Split(' ').Length; i < rawProductList.Count; i++)
                    {
                        if (!rawProductList[i].Trim().Contains(parserResults[ProductLevel.SMAAK].Split(' ').ToList()[0]))
                            formaatWords.Add(rawProductList[i].Trim());
                    }

                    ClearLevels(ProductLevel.FORMAAT);
                }

                if (formaatWords.Count != 0)
                    parserResults[ProductLevel.FORMAAT] = string.Join(" ", formaatWords.ToArray());
            }

            // SMAAK
            if (!parserResults.ContainsKey(ProductLevel.SMAAK) && parserResults.ContainsKey(ProductLevel.FORMAAT))
            {
                string smaak = rawProduct.Substring(rawProduct.IndexOf(parserResults[ProductLevel.FORMAAT]) + parserResults[ProductLevel.FORMAAT].Length).Trim();
                if (smaak.Length > 0)
                    parserResults[ProductLevel.SMAAK] = smaak;
            }
            else if (parserResults.ContainsKey(ProductLevel.SMAAK) && !(rawProduct.Contains('(') && rawProduct.Contains(')')))
            {
                if (!rawProduct.Contains(parserResults[ProductLevel.BELEVING]))
                {
                    parserResults[ProductLevel.SMAAK] = rawProduct.Substring(rawProduct.IndexOf(parserResults[ProductLevel.FORMAAT]) + parserResults[ProductLevel.FORMAAT].Length).Trim();
                    ClearLevels(ProductLevel.SMAAK);
                }
            }

            // UPC
            if (!parserResults.ContainsKey(ProductLevel.BARCODE) && parserResults.ContainsKey(ProductLevel.SMAAK))
            {
                if (rawProduct.Contains('(') && rawProduct.Contains(')') && rawProduct.Contains(parserResults[ProductLevel.SMAAK]))
                {
                    int start = rawProduct.IndexOf('(');
                    int end = rawProduct.IndexOf(')');
                    parserResults[ProductLevel.BARCODE] = rawProduct.Substring(start + 1, end - start - 1);
                }
            }
            else if (parserResults.ContainsKey(ProductLevel.BARCODE))
            {
                if (rawProduct.Contains('(') && rawProduct.Contains(')') && rawProduct.Contains(parserResults[ProductLevel.SMAAK]))
                {
                    int start = rawProduct.IndexOf('(');
                    int end = rawProduct.IndexOf(')');
                    parserResults[ProductLevel.BARCODE] = rawProduct.Substring(start + 1, end - start - 1);
                }
            }

            return parserResults;
        }

        private void ClearLevels(ProductLevel level)
        {
            switch (level)
            {
                case ProductLevel.MAJOR_BRAND:
                    parserResults.Remove(ProductLevel.APPARAAT);
                    parserResults.Remove(ProductLevel.TYPE);
                    parserResults.Remove(ProductLevel.BELEVING);
                    parserResults.Remove(ProductLevel.SOORT);
                    parserResults.Remove(ProductLevel.FORMAAT);
                    parserResults.Remove(ProductLevel.SMAAK);
                    parserResults.Remove(ProductLevel.BARCODE);
                    break;
                case ProductLevel.APPARAAT:
                    parserResults.Remove(ProductLevel.TYPE);
                    parserResults.Remove(ProductLevel.BELEVING);
                    parserResults.Remove(ProductLevel.SOORT);
                    parserResults.Remove(ProductLevel.FORMAAT);
                    parserResults.Remove(ProductLevel.SMAAK);
                    parserResults.Remove(ProductLevel.BARCODE);
                    break;
                case ProductLevel.TYPE:
                    parserResults.Remove(ProductLevel.BELEVING);
                    parserResults.Remove(ProductLevel.SOORT);
                    parserResults.Remove(ProductLevel.FORMAAT);
                    parserResults.Remove(ProductLevel.SMAAK);
                    parserResults.Remove(ProductLevel.BARCODE);
                    break;
                case ProductLevel.BELEVING:
                    parserResults.Remove(ProductLevel.SOORT);
                    parserResults.Remove(ProductLevel.FORMAAT);
                    parserResults.Remove(ProductLevel.SMAAK);
                    parserResults.Remove(ProductLevel.BARCODE);
                    break;
                case ProductLevel.SOORT:
                    parserResults.Remove(ProductLevel.FORMAAT);
                    parserResults.Remove(ProductLevel.SMAAK);
                    parserResults.Remove(ProductLevel.BARCODE);
                    break;
                case ProductLevel.FORMAAT:
                    parserResults.Remove(ProductLevel.SMAAK);
                    parserResults.Remove(ProductLevel.BARCODE);
                    break;
                case ProductLevel.SMAAK:
                    parserResults.Remove(ProductLevel.BARCODE);
                    break;
            }
        }
    }
}
